import React, { useEffect, useState } from "react";
import classNames from "classnames";
import { TreeData } from "./data";
import TreeNode from "./TreeNode";
import { deepClone } from "./utils";

interface Props {
  data: TreeData;
}
interface keyNodeMap {
  //属性值任意，节点是一个TreeData
  [key: string]: TreeData;
}
const Tree: React.FC<Props> = (props) => {
  let keyNodeMap: keyNodeMap = {}; //key就是节点的key，值就是节点本身
  let [data,setData] = useState(props.data)
  useEffect(()=>{
    buildKeyMap(props.data)
  })
  //折叠
  const onCollapse = (key: string) => {
    let data = keyNodeMap[key];
    if (data) {
      let {children} = data
      if(children){
        data.collapsed = !data.collapsed;
        data.children = data.children || [];
        let data1 = deepClone(data)
        setData(data1)
      }
     
    }
  };
  //选择框
  const onCheck = (key:string) =>{
    let data = keyNodeMap[key];
    if(data){
        data.checked = !data.checked //先把自己取反
        if(data.checked){//如果新的状态为true的话
            checkChildren(data.children,true)//选中所有的儿子
            checkParent(data.parent!)//如果一个节点，它所有的子节点都被选中了，自己也要被选中
        }else{
            checkChildren(data.children,false)//让所有的下级节点取消选中
            // cancelParentChecked()
        }
        let data2 = deepClone(data)
        setData(data2)
    }
  }
  // const cancelParentChecked = () =>{

  // }
  const checkParent = (parent:TreeData) =>{
    while(parent){
        parent.checked = parent.children.every((item:TreeData)=>item.checked)//判断孩子有没有都被选中，如果都被选中，则返回true
        parent = parent.parent!; //再去找他爷爷
    }
  }
  const checkChildren = (children:TreeData[] = [],checked:boolean) =>{
    children.forEach((item:TreeData)=>{
        item.checked = checked
        checkChildren(item.children,checked);
      
    })
  }
  const buildKeyMap = (data:any) => {
    keyNodeMap[data.key] = data; //data是根节点1
    if (data.children && data.children.length > 0) {
      walk(data.children, data);
    }
  };
  const walk = (children: TreeData[], parent: TreeData): void => {
    children.forEach((item: TreeData) => {
      item.parent = parent; //在节点上增加一个parent属性,指向自己的父亲
      keyNodeMap[item.key] = item;
      if (item.children && item.children.length > 0) {
        walk(item.children, item);
      }
    });
  };
  return (
    <div className="tree">
      <div className="treeNodes">
        <TreeNode 
            onCollapse={onCollapse} 
            onCheck={onCheck}
            data={props.data} 
        />
      </div>
    </div>
  );
};

export default Tree;
